#include "Unit.h"
#include <stdio.h>
#include <iostream>
#include <sstream>

////////////////////////////////Local Declare///////////////////////////////
static void removeLastBlank(std::string& str) {
  str.erase(str.size() - 1, 1);
}

////////////////////////////////Public Declare//////////////////////////////
Unit::Unit(unsigned int convertToAmountFactor, const char* name, const Unit* next) 
  :m_convertToAmountFactor(convertToAmountFactor)
  ,m_name(name)
  ,m_NextUnit(next){

}

unsigned int Unit::convertToAmount(unsigned int dimention) const { 
  return (m_convertToAmountFactor*dimention);
}

void Unit::convertToDimension(const unsigned int amount, unsigned int& integralDimension, unsigned int& residualDimension) const{
  integralDimension = (amount / m_convertToAmountFactor);
  residualDimension = (amount % m_convertToAmountFactor);
}

void Unit::formatDimenstion(const unsigned int dimension, std::string& str) const {
  if(dimension) {
    std::stringstream sstream;
    sstream << dimension << " " << m_name << " ";
    str += sstream.str();
  }
}

const Unit& Unit::getBaseUnit() const {
  const Unit* pUnit = this;
  while(pUnit->m_NextUnit)
    pUnit = pUnit->m_NextUnit;
  return *pUnit;
}

const Unit& Unit::getMaxUnit() const {
  return *getBaseUnit().m_NextUnit;
}

std::string Unit::toString(const unsigned int amount, const Unit& formatUnit) const {
  unsigned int integral, residual = amount;
  const Unit* unit;
  std::string str;
  str.clear();
  
  unit = &formatUnit;
  do {
    unit->convertToDimension(residual, integral, residual);
    unit->formatDimenstion(integral, str);
  }
  while(unit = unit->m_NextUnit);
  
  removeLastBlank(str);

  return str;
}
